#include <iostream>
#include <vector>
#include <pthread.h>
#include <unistd.h>

int g_tickets = 10000;           // 总票数 ... 共享资源
int tickets_per_thread;          // 每个线程应该抢到的票数
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一把锁
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;    // 定义一个条件变量
int start_flag = 0;              // 标记线程是否可以开始抢票

void *route(void *args)
{
    pthread_mutex_lock(&mutex);
    while (!start_flag)
    {
        pthread_cond_wait(&cond, &mutex); // 等待主线程发出开始抢票的信号
    }
    pthread_mutex_unlock(&mutex);

    int thread_tickets = 0; // 每个线程抢的票数
    while (thread_tickets < tickets_per_thread)
    {
        pthread_mutex_lock(&mutex); // 加锁
        if (g_tickets > 0)
        {
            g_tickets--;
            thread_tickets++;
        }
        pthread_mutex_unlock(&mutex); // 解锁

        // 模拟抢票后的其他操作
        usleep(100); // 休眠一段时间，模拟其他操作
    }
    std::cout << "I am new thread, I snap up tickets = " << thread_tickets << std::endl; // 统计当前线程抢到的票数
    return nullptr;
}

int main()
{
    const size_t num_threads = 5;
    tickets_per_thread = g_tickets / num_threads; // 计算每个线程应该抢到的票数

    std::vector<pthread_t> threads;

    // 1、创建线程
    for (size_t i = 0; i < num_threads; ++i)
    {
        pthread_t tid;
        pthread_create(&tid, nullptr, route, nullptr);
        threads.push_back(tid);
    }

    // 2、主线程控制线程同步
    pthread_mutex_lock(&mutex);
    start_flag = 1; // 设置开始抢票的标志
    pthread_cond_broadcast(&cond); // 唤醒所有等待线程
    pthread_mutex_unlock(&mutex);

    // 3、等待线程
    for (auto &thread : threads)
    {
        pthread_join(thread, nullptr);
    }

    std::cout << "tickets = " << g_tickets << std::endl;
    return 0;
}